package category

import (
	// "github.com/buger/jsonparser"
	// "regexp"
	"github.com/gin-gonic/gin"
	log "github.com/sirupsen/logrus"
	// "strings"
	"strconv"
	"net/http"
	"conf"
	"libs/db"
	"io/ioutil"
	"encoding/json"
)

type Controller struct {
	config *conf.Config
	redis  *db.Redis
	model  *Model
}

// func New(c *gin.Context) *Controller{
func New(config *conf.Config) *Controller{
	controller  := new(Controller)
	// config
	controller.config = config
	// redis
	// controller.redis  = db.NewRedis(config.Redis.Host, config.Redis.Port)
	// model
	controller.model  = NewModel(config.Mongodb.Host,config.Mongodb.Port, config.Mongodb.GetDbName("category"))
	return controller
}

func (this *Controller) Get(c *gin.Context) {
	id       := c.Param("id")
	language := this.GetLanguage(c)
	var err error
	var res interface{}
	total := 0
	if len(id) == 24 {
		res, err = this.model.FindOne(id, this.GetLangDb(language))
	}else{
		var limit,page int
		limit, err= strconv.Atoi(c.Query("limit"))
		if limit < 1 {
			limit = 20
		}
		page, err = strconv.Atoi(c.Query("page"))
		if page < 1 {
			page  = 1
		}
		skip := (page - 1) * limit
		res, err   = this.model.FindAll(skip, limit, this.GetLangDb(language))
		total, err = this.model.Count(language)
	}
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"success": false, "errno": 1000, "errmsg": err.Error()})
	}else{
		c.JSON(http.StatusOK, gin.H{"success": true, "errno": 0, "data": res, "total": total})
	}
	return 
}

func (this *Controller) Post(c *gin.Context) {
	var body, res JsonData
	var err  error
	body, err = this.GetBodyJson(c)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"success": false, "errno": 1000, "errmsg": err.Error()})
		return
	}
	language  := body.Language;
	if(len(language) < 1){
		language = this.GetLanguage(c)
	}
	body.Language = language
	res, err  = this.model.Insert(body, this.GetLangDb(language))
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"success": false, "errno": 1000, "errmsg": err.Error()})
	}else{
		c.JSON(http.StatusOK, gin.H{"success": true, "errno": 0, "data": res})
	}
	return
}

func (this *Controller) Delete(c *gin.Context) {
	id       := c.Param("id")
	language := this.GetLanguage(c)
	var err error
	var res interface{}
	res, err = this.model.Delete(id, this.GetLangDb(language))
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"success": false, "errno": 1000, "errmsg": err.Error()})
	}else{
		c.JSON(http.StatusOK, gin.H{"success": true, "errno": 0, "data": res})
	}
	return
}

func (this *Controller) Put(c *gin.Context) {
	id       := c.Param("id")
	var body, res JsonData
	var err  error
	body, err = this.GetBodyJson(c)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"success": false, "errno": 1000, "errmsg": err.Error()})
		return
	}
	language  := body.Language;
	if(len(language) < 1){
		language = this.GetLanguage(c)
	}
	body.Language = language
	res, err = this.model.Update(id, body, this.GetLangDb(language))
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"success": false, "data": "", "msg": err.Error()})
	}else{
		c.JSON(http.StatusOK, gin.H{"success": true, "data": res})
	}
	return 
}


func (this *Controller) GetLanguage(c *gin.Context) string{
	language := c.Query("language")
	return language
}

func (this *Controller) GetLangDb(lang string) string{
	return this.config.Lang.GetLangDb(lang) 
}

func (this *Controller) GetBodyByte(c *gin.Context) []byte {
	body, err:= ioutil.ReadAll(c.Request.Body)
	if err != nil {
		log.Errorf("request[%s] body error: %s", c.Request.URL.String(), err.Error())
		c.JSON(http.StatusBadRequest, gin.H{"success": false, "errno": 1000, "errmsg": err.Error()})
		return body
	}
	return body
}

func (this *Controller) GetBodyJson(c *gin.Context) (JsonData, error) {
	var data JsonData
	body, err:= ioutil.ReadAll(c.Request.Body)
	if err != nil {
		log.Errorf("request[%s] body error: %s", c.Request.URL.String(), err.Error())
		return data,err
	}
	err = json.Unmarshal(body, &data)
	if err != nil {
		log.Errorf("json unmarshal request body[%s] error[%s]", string(body), err.Error())
		return data,err
	}
	return data,err
}

/*

func Get(c *gin.Context) {
	id       := c.Param("id")
	language := c.Query("language")
	var err error
	var res interface{}
	total := 0
	if len(id) == 24 {
		res, err = model.FindOneById(id, language)
	}else{
		var limit,page int
		limit, err= strconv.Atoi(c.Query("limit"))
		if limit < 1 {
			limit = 20
		}
		page, err = strconv.Atoi(c.Query("page"))
		if page < 1 {
			page  = 1
		}
		skip := (page - 1) * limit
		res, err = model.FindAll(skip, limit, language)
		total, err = model.Count(language)
	}
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"success": false, "data": "", "msg": err.Error()})
	}else{
		c.JSON(http.StatusOK, gin.H{"success": true, "data": res, "total": total})
	}
	return 
}


func Post(c *gin.Context) {
	body     := model.GetBodyJson(c)
	language := body.Language;
	if(len(language) < 1){
		language = c.Query("language")
	}
	body.Language = language
	res,err  := model.Insert(body, language)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"success": false, "data": "", "msg": err.Error()})
	}else{
		c.JSON(http.StatusOK, gin.H{"success": true, "data": res})
	}
	return 
}

func Put(c *gin.Context) {
	id       := c.Param("id")
	body     := model.GetBodyJson(c)
	language := body.Language;
	if(len(language) < 1){
		language = c.Query("language")
	}
	body.Language = language
	var err error
	var res interface{}
	res, err = model.UpdateOneById(id, body, language)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"success": false, "data": "", "msg": err.Error()})
	}else{
		c.JSON(http.StatusOK, gin.H{"success": true, "data": res})
	}
	return
}

func Delete(c *gin.Context) {
	id       := c.Param("id")
	language := c.Query("language")
	var err error
	var res interface{}
	res, err = model.DeleteOneById(id, language)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"success": false, "data": "", "msg": err.Error()})
	}else{
		c.JSON(http.StatusOK, gin.H{"success": true, "data": res})
	}
	return 
}
*/